/******************************************************************************
 
 
 ******************************************************************************
    Modification:  2016-03 Created
******************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>   //mmap
#include <linux/fb.h>


#include "hi_common.h"
#include "hi_type.h"
#include "hi_comm_vb.h"
#include "hi_comm_sys.h"
#include "hi_comm_venc.h"
#include "hi_comm_vi.h"
#include "hi_comm_vo.h"
//#include "hi_comm_group.h"
#include "hi_comm_region.h"

#include "mpi_vb.h"
#include "mpi_sys.h"
#include "mpi_venc.h"
#include "mpi_vi.h"
#include "mpi_vo.h"
#include "mpi_region.h"
#include "sample_comm.h"



#include "hifb.h"
#include "loadbmp.h"
#include "hi_comm_region.h"


#include "hi_tde_api.h"
#include "hi_tde_type.h"
#include "hi_tde_errcode.h"

#include "sample_comm.h"
#include "sysarch.h"
#include "video.h"
#include "MenuIf.h"

static VO_INTF_SYNC_E gs_enIntfSync = VO_OUTPUT_NTSC;		//VO_OUTPUT_PAL;
static VIDEO_NORM_E gs_enNorm = VIDEO_ENCODING_MODE_NTSC;	//VIDEO_ENCODING_MODE_PAL;
static HI_U32 gs_u32ViFrmRate = 30; 						//25;


/* sp420 ת��Ϊ p420 ; sp422 ת��Ϊ p422  */
void sample_yuv_dump(VIDEO_FRAME_S * pVBuf, FILE *pfd)
{
    unsigned int w, h;
    char * pVBufVirt_Y;
    char * pVBufVirt_C;
    char * pMemContent;
    unsigned char TmpBuff[4096];                //������ֵ̫С��ͼ��ܴ�Ļ��治��
    HI_U32 phy_addr,Ysize,Csize;
    PIXEL_FORMAT_E  enPixelFormat = pVBuf->enPixelFormat;
    HI_U32 u32UvHeight;/* ��Ϊplanar ��ʽʱ��UV�����ĸ߶� */

    Ysize = (pVBuf->u32Stride[0])*(pVBuf->u32Height);
    if (PIXEL_FORMAT_YUV_SEMIPLANAR_420 == enPixelFormat)
    {
        Csize = (pVBuf->u32Stride[1])*(pVBuf->u32Height)/2;    
        u32UvHeight = pVBuf->u32Height/2;
    }
    else
    {
        Csize = (pVBuf->u32Stride[1])*(pVBuf->u32Height);   
        u32UvHeight = pVBuf->u32Height;
    }

    phy_addr = pVBuf->u32PhyAddr[0];

    //printf("phy_addr:%x, size:%d\n", phy_addr, size);
    pVBufVirt_Y = (HI_CHAR *) HI_MPI_SYS_Mmap(phy_addr, Ysize);	
    if (NULL == pVBufVirt_Y)
    {
        return;
    }

    pVBufVirt_C = (HI_CHAR *) HI_MPI_SYS_Mmap(pVBuf->u32PhyAddr[1], Csize);
    if (NULL == pVBufVirt_C)
    {
        HI_MPI_SYS_Munmap(pVBufVirt_Y, Ysize); 
        return;
    }

    /* save Y ----------------------------------------------------------------*/
    fprintf(stderr, "saving......Y......");
    fflush(stderr);
    for(h=0; h<pVBuf->u32Height; h++)
    {
        pMemContent = pVBufVirt_Y + h*pVBuf->u32Stride[0];
        fwrite(pMemContent, pVBuf->u32Width, 1, pfd);
    }
    fflush(pfd);
    

    /* save U ----------------------------------------------------------------*/
    fprintf(stderr, "U......");
    fflush(stderr);
    for(h=0; h<u32UvHeight; h++)
    {
        pMemContent = pVBufVirt_C + h*pVBuf->u32Stride[1];

        pMemContent += 1;

        for(w=0; w<pVBuf->u32Width/2; w++)
        {
            TmpBuff[w] = *pMemContent;
            pMemContent += 2;
        }
        fwrite(TmpBuff, pVBuf->u32Width/2, 1, pfd);
    }
    fflush(pfd);

    /* save V ----------------------------------------------------------------*/
    fprintf(stderr, "V......");
    fflush(stderr);
    for(h=0; h<u32UvHeight; h++)    
    {
        pMemContent = pVBufVirt_C + h*pVBuf->u32Stride[1];

        for(w=0; w<pVBuf->u32Width/2; w++)
        {
            TmpBuff[w] = *pMemContent;
            pMemContent += 2;
        }
        fwrite(TmpBuff, pVBuf->u32Width/2, 1, pfd);
    }
    fflush(pfd);
    
    fprintf(stderr, "done %d!\n", pVBuf->u32TimeRef);
    fflush(stderr);
    
    HI_MPI_SYS_Munmap(pVBufVirt_Y, Ysize);  
    HI_MPI_SYS_Munmap(pVBufVirt_C, Csize);

}

static HI_S32 s_s32MemDev = 0;

HI_S32 memopen( void )
{
    if (s_s32MemDev <= 0)
    {
        s_s32MemDev = open ("/dev/mem", O_CREAT|O_RDWR|O_SYNC);
        if (s_s32MemDev <= 0)
        {
            return -1;
        }
    }
    return 0;
}

HI_VOID memclose()
{
	close(s_s32MemDev);
}

HI_S32 SAMPLE_MISC_WbcDump(VI_CHN ViChn, HI_U32 u32Cnt)
{
    HI_S32 i, s32Ret;
    VIDEO_FRAME_INFO_S stFrame;
    //VIDEO_FRAME_INFO_S astFrame[256];
    HI_CHAR szYuvName[128];
    HI_CHAR szPixFrm[10];
    FILE *pfd;

    printf("\nNOTICE: This tool only can be used for TESTING !!!\n");
    printf("usage: ./vou_wbc_dump [ViChn] [frmcnt]. sample: ./vou_wbc_dump 0 5\n\n");

    //HI_MPI_VO_SetWbcDepth(ViChn, 1);

    /* Get Frame to make file name*/
    s32Ret = HI_MPI_VI_GetFrame(ViChn, &stFrame);
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_VO(%d)_WbcGetScreenFrame errno %#x\n", ViChn, s32Ret);
        return -1;
    }

    /* make file name */
    strcpy(szPixFrm,
    (PIXEL_FORMAT_YUV_SEMIPLANAR_420 == stFrame.stVFrame.enPixelFormat)?"p420":"p422");
    sprintf(szYuvName, "./Wbc(%d)_%d_%d_%s_%d.yuv",ViChn,
        stFrame.stVFrame.u32Width, stFrame.stVFrame.u32Height,szPixFrm,u32Cnt);
    printf("Dump YUV frame of Wbc(%d) to file: \"%s\"\n",ViChn, szYuvName);

    HI_MPI_VI_ReleaseFrame(ViChn, &stFrame);

    /* open file */
    pfd = fopen(szYuvName, "wb");

    if (NULL == pfd)
    {
        return -1;
    }
    
    memopen();

    /* get VO frame  */
    for (i=0; i<u32Cnt; i++)
    {
        s32Ret = HI_MPI_VI_GetFrame(ViChn, &stFrame);
        if (HI_SUCCESS != s32Ret)
        {
            printf("get Wbc(%d) frame err\n", ViChn);
            printf("only get %d frame\n", i);
            break;
        }
        /* save VO frame to file */
		sample_yuv_dump(&stFrame.stVFrame, pfd);

        /* release frame after using */
        s32Ret = HI_MPI_VI_ReleaseFrame(ViChn, &stFrame);
        if (HI_SUCCESS != s32Ret)
        {
            printf("release Wbc(%d) frame err\n", ViChn);
            printf("only get %d frame\n", i);
            break;
        }
    }

    memclose();

    fclose(pfd);

	return 0;
}

int  gVoFbWidth = 720;
int  gVoFbHeight = 480;


#define SAMPLE_IMAGE_WIDTH     300
#define SAMPLE_IMAGE_HEIGHT    150
#define SAMPLE_IMAGE_SIZE      (300*150*2)
#define SAMPLE_IMAGE_NUM       1000

#define SAMPLE_IMAGE_PATH		"./res/%d.bmp"
#define SAMPLE_CURSOR_PATH		"./res/cursor.bmp"


#define HIFB_RED_1555   0xfc00
#define HIFB_GREEN_1555   0x03e0

#define SAMPLE_VIR_SCREEN_WIDTH	    SAMPLE_IMAGE_WIDTH			/*virtual screen width*/
#define SAMPLE_VIR_SCREEN_HEIGHT	SAMPLE_IMAGE_HEIGHT*2		/*virtual screen height*/
#define s32fd 0
#define HIL_MMB_NAME_LEN 16
#define g_s32fd  0
/*if you want to use standard mode ,please delete this define*/
//#define ExtendMode


#define DIF_LAYER_NAME_LEN 20
#define HIL_MMZ_NAME_LEN 32

typedef enum
{
    HIFB_LAYER_0 = 0x0,
    HIFB_LAYER_1,
    HIFB_LAYER_2,
    HIFB_LAYER_CURSOR_0,
    HIFB_LAYER_ID_BUTT
} HIFB_LAYER_ID_E;

typedef struct
{
    HIFB_LAYER_ID_E     sLayerID;
    HI_CHAR             sLayerName[DIF_LAYER_NAME_LEN];
}LayerID_NAME_S;

typedef struct
{
    int fd;
    int layer;
    int ctrlkey;
}PTHREAD_HIFB_SAMPLE_INFO;





static struct fb_bitfield g_r16 = {10, 5, 0};
static struct fb_bitfield g_g16 = {5, 5, 0};
static struct fb_bitfield g_b16 = {0, 5, 0};
static struct fb_bitfield g_a16 = {15, 1, 0};


HI_S32 SAMPLE_HIFB_LoadBmp(const char *filename, HI_U8 *pAddr)
{
    OSD_SURFACE_S Surface;
    OSD_BITMAPFILEHEADER bmpFileHeader;
    OSD_BITMAPINFO bmpInfo;

    if(GetBmpInfo(filename,&bmpFileHeader,&bmpInfo) < 0)
    {
		printf("GetBmpInfo err!\n");
        return HI_FAILURE;
    }

    Surface.enColorFmt = OSD_COLOR_FMT_RGB1555;

    CreateSurfaceByBitMap(filename,&Surface,pAddr);

    return HI_SUCCESS;
}
#if 0
HI_VOID *SAMPLE_HIFB_PANDISPLAY(void *pData)
{
    HI_S32 i,x,y,s32Ret;
	TDE_HANDLE s32Handle;
    struct fb_fix_screeninfo fix;
    struct fb_var_screeninfo var;
    HI_U32 u32FixScreenStride = 0;
    unsigned char *pShowScreen;
    unsigned char *pHideScreen;
	HI_U32 u32HideScreenPhy = 0;
	HI_U16 *pShowLine;
    HIFB_ALPHA_S stAlpha;
    HIFB_POINT_S stPoint = {0, 0};
    char file[12] = "/dev/fb0";
	HI_BOOL g_bCompress = HI_FALSE;

    char image_name[128];
	HI_U8 *pDst = NULL;
    HI_BOOL bShow;
    PTHREAD_HIFB_SAMPLE_INFO *pstInfo;
	HIFB_COLORKEY_S stColorKey;
	TDE2_RECT_S stSrcRect,stDstRect;
	TDE2_SURFACE_S stSrc,stDst;
	HI_U32 Phyaddr;
	HI_VOID *Viraddr;

    if(HI_NULL == pData)
    {
        return HI_NULL;
    }

    pstInfo = (PTHREAD_HIFB_SAMPLE_INFO *)pData;
    switch (pstInfo->layer)
    {
        case 0 :
            strcpy(file, "/dev/fb0");
            break;
        case 1 :
            strcpy(file, "/dev/fb1");
            break;
        case 2 :
            strcpy(file, "/dev/fb2");
            break;
        case 3 :
            strcpy(file, "/dev/fb3");
            break;
        default:
            strcpy(file, "/dev/fb0");
            break;
    }

    /* 1. open framebuffer device overlay 0 */
    pstInfo->fd = open(file, O_RDWR, 0);
    if(pstInfo->fd < 0)
    {
        printf("open %s failed!\n",file);
        return HI_NULL;
    }

	if(pstInfo->layer == HIFB_LAYER_0)
	{
		if (ioctl(pstInfo->fd, FBIOPUT_COMPRESSION_HIFB, &g_bCompress) < 0)
		{
			printf("Func:%s line:%d FBIOPUT_COMPRESSION_HIFB failed!\n",
			__FUNCTION__, __LINE__);
			close(pstInfo->fd);
			return HI_NULL;
		}
	}

    bShow = HI_FALSE;
    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)
    {
        printf("FBIOPUT_SHOW_HIFB failed!\n");
        return HI_NULL;
    }

    /* 2. set the screen original position */
	stPoint.s32XPos = 0;
    stPoint.s32YPos = 0;
    if (ioctl(pstInfo->fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)
    {
        printf("set screen original show position failed!\n");
		close(pstInfo->fd);
        return HI_NULL;
    }

    /* 3.set alpha */
    stAlpha.bAlphaEnable = HI_FALSE;
    stAlpha.bAlphaChannel = HI_FALSE;
    stAlpha.u8Alpha0 = 0x0;
    stAlpha.u8Alpha1 = 0xff;
    stAlpha.u8GlobalAlpha = 0x80;
    if (ioctl(pstInfo->fd, FBIOPUT_ALPHA_HIFB,  &stAlpha) < 0)
    {
        printf("Set alpha failed!\n");
		close(pstInfo->fd);
        return HI_NULL;
    }

	/*all layer surport colorkey*/
	stColorKey.bKeyEnable = HI_TRUE;
	stColorKey.u32Key = 0x0;
	if (ioctl(pstInfo->fd, FBIOPUT_COLORKEY_HIFB, &stColorKey) < 0)
	{
		printf("FBIOPUT_COLORKEY_HIFB!\n");
		close(pstInfo->fd);
		return HI_NULL;
	}

    /* 4. get the variable screen info */
    if (ioctl(pstInfo->fd, FBIOGET_VSCREENINFO, &var) < 0)
    {
        printf("Get variable screen info failed!\n");
		close(pstInfo->fd);
        return HI_NULL;
    }

    /* 5. modify the variable screen info
          the screen size: IMAGE_WIDTH*IMAGE_HEIGHT
          the virtual screen size: VIR_SCREEN_WIDTH*VIR_SCREEN_HEIGHT
          (which equals to VIR_SCREEN_WIDTH*(IMAGE_HEIGHT*2))
          the pixel format: ARGB1555
    */

    usleep(5000);

    var.xres_virtual = gVoFbWidth;
	var.yres_virtual = gVoFbHeight*2;
	var.xres = gVoFbWidth;
	var.yres = gVoFbHeight;

    var.transp= g_a16;
    var.red = g_r16;
    var.green = g_g16;
    var.blue = g_b16;
    var.bits_per_pixel = 16;
    var.activate = FB_ACTIVATE_NOW;

    /* 6. set the variable screeninfo */
    if (ioctl(pstInfo->fd, FBIOPUT_VSCREENINFO, &var) < 0)
    {
        printf("Put variable screen info failed!\n");
		close(pstInfo->fd);
        return HI_NULL;
    }

    /* 7. get the fix screen info */
    if (ioctl(pstInfo->fd, FBIOGET_FSCREENINFO, &fix) < 0)
    {
        printf("Get fix screen info failed!\n");
		close(pstInfo->fd);
        return HI_NULL;
    }
    u32FixScreenStride = fix.line_length;   /*fix screen stride*/

    /* 8. map the physical video memory for user use */
    pShowScreen = (unsigned char *)mmap(HI_NULL, fix.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, pstInfo->fd, 0);
    if(MAP_FAILED == pShowScreen)
    {
        printf("mmap framebuffer failed!\n");
		close(pstInfo->fd);
        return HI_NULL;
    }

    memset(pShowScreen, 0x00, fix.smem_len);

    /* time to paly*/
    bShow = HI_TRUE;
    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)
    {
        printf("FBIOPUT_SHOW_HIFB failed!\n");
        munmap(pShowScreen, fix.smem_len);
        return HI_NULL;
    }

    //�����Բ���Щ�����ƶ�
    //ʹ�ô˽ӿ����õ��Ӳ�����Ļ����ʾ����ʼ����꣬��귶Χ�ӣ�0, 0�����õ��Ӳ�֧�ֵ����ֱ���֮�䡣

	printf("show cursor\n");
	SAMPLE_HIFB_LoadBmp(SAMPLE_CURSOR_PATH, pShowScreen);
	if (ioctl(pstInfo->fd, FBIOPAN_DISPLAY, &var) < 0)	//ˢ��
	{
		printf("FBIOPAN_DISPLAY failed!\n");
		munmap(pShowScreen, fix.smem_len);
		close(pstInfo->fd);
		return NULL;
	}


	var.yoffset = 0;

	pHideScreen = pShowScreen + (u32FixScreenStride*var.yres)*(i%2);
	memset(pHideScreen, 0x00, u32FixScreenStride*var.yres);
	u32HideScreenPhy = fix.smem_start + (i%2)*u32FixScreenStride*var.yres;

	pShowLine = (HI_U16*)pHideScreen;


	//����
	for (y = gVoFbHeight/2-2; y < gVoFbHeight/2+2; y++)
	{
		for (x = gVoFbWidth/2-2; x < gVoFbWidth/2+2; x++)
		{
			*(pShowLine + y * var.xres + x) = HIFB_RED_1555;
		}
	}


	for (y = 0; y < 2; y++)
	{
		for (x = gVoFbWidth/2-2; x < gVoFbWidth/2+2; x++)
		{
			*(pShowLine + y * var.xres + x) = HIFB_RED_1555;
		}
	}

	for (y = gVoFbHeight-2; y < gVoFbHeight; y++)
	{
		for (x = gVoFbWidth/2-2; x < gVoFbWidth/2+2; x++)
		{
			*(pShowLine + y * var.xres + x) = HIFB_RED_1555;
		}
	}

	for (x = 0; x < 2; x++)
	{
		for (y = gVoFbHeight/2-2; y < gVoFbHeight/2+2; y++)
		{
			*(pShowLine + y * var.xres + x) = HIFB_RED_1555;
		}
	}

	for (x = gVoFbWidth-2; x < gVoFbWidth; x++)
	{
		for (y = gVoFbHeight/2-2; y < gVoFbHeight/2+2; y++)
		{
			*(pShowLine + y * var.xres + x) = HIFB_RED_1555;
		}
	}


	printf("move cursor\n");
	HI_U32 u32PosXtemp;
	u32PosXtemp = stPoint.s32XPos;

    for(i=0; i<400; i++)
    {
        if(i > 200)
        {
            stPoint.s32XPos = u32PosXtemp + i%20;
            stPoint.s32YPos--;
        }
        else
        {
            stPoint.s32XPos = u32PosXtemp - i%20;
            stPoint.s32YPos++;
        }
        if(ioctl(pstInfo->fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)
        {
            printf("set screen original show position failed!\n");
			munmap(pShowScreen, fix.smem_len);
			close(pstInfo->fd);
            return HI_NULL;
        }

        usleep(70*1000);
    }

    /* unmap the physical memory */
    munmap(pShowScreen, fix.smem_len);
    bShow = HI_FALSE;
    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)
	{
		printf("FBIOPUT_SHOW_HIFB failed!\n");
		return HI_NULL;
	}
    close(pstInfo->fd);
    return HI_NULL;
}

#endif

int Line(int x0, int y0, int x1, int y1, HI_U16 *pBuf)
{
	int x,y;

	if (pBuf == NULL)
		return -1;

	for (y = y0; y < y1; y++)
	{
		for (x = x0; x < x1; x++)
		{
			*(pBuf + y * gVoFbWidth + x) = HIFB_RED_1555;
		}
	}
}

HI_U8 gMenuRefreshFlg = 1;
HI_U16 *g_pwMenuViraddr;

TThreadRet MenuThread(void* pvPara)
{
    HI_S32 s32Ret = HI_SUCCESS;
    HIFB_LAYER_INFO_S stLayerInfo ;
    HIFB_BUFFER_S stCanvasBuf;
    HI_U16 *pBuf;
	HI_U8 *pDst = NULL;
    HI_U32 x, y,i;
	char image_name[128];
	HI_BOOL Show;
	HI_BOOL bCompress = HI_TRUE;
    HIFB_POINT_S stPoint = {0};
    struct fb_var_screeninfo stVarInfo;
	char file[12] = "/dev/fb0";
    HI_U32 maxW,maxH;
	PTHREAD_HIFB_SAMPLE_INFO *pstInfo;
	pstInfo = (PTHREAD_HIFB_SAMPLE_INFO *)pvPara;
	HIFB_COLORKEY_S stColorKey;
	TDE2_RECT_S stSrcRect,stDstRect;
	TDE2_SURFACE_S stSrc,stDst;
	HI_U32 Phyaddr;
	HI_VOID *Viraddr;
	TDE_HANDLE s32Handle;

	switch (pstInfo->layer)
	{
		case 0 :
			strcpy(file, "/dev/fb0");
			break;
		case 1 :
			strcpy(file, "/dev/fb1");
			break;
		case 2 :
			strcpy(file, "/dev/fb2");
			break;
		case 3 :
			strcpy(file, "/dev/fb3");
			break;
		case 4 :
			strcpy(file, "/dev/fb4");
			break;

		default:
			strcpy(file, "/dev/fb0");
			break;
	}

	memset(&stLayerInfo, 0, sizeof(stLayerInfo));

		/* 1. open framebuffer device overlay 0 */
	pstInfo->fd = open(file, O_RDWR, 0);
	if(pstInfo->fd < 0)
	{
		printf("open %s failed!\n",file);
		return HI_NULL;
	}

	if(pstInfo->layer == HIFB_LAYER_0 )
	{
		if (ioctl(pstInfo->fd, FBIOPUT_COMPRESSION_HIFB, &bCompress) < 0)
		{
			printf("FBIOPUT_COMPRESSION_HIFB failed!\n");
			close(pstInfo->fd);
			return HI_NULL;
		}
	}
	/*all layer surport colorkey*/
	stColorKey.bKeyEnable = HI_TRUE;
	stColorKey.u32Key = 0x0;
	if (ioctl(pstInfo->fd, FBIOPUT_COLORKEY_HIFB, &stColorKey) < 0)
	{
	printf("FBIOPUT_COLORKEY_HIFB!\n");
	close(pstInfo->fd);
	return HI_NULL;
	}
    s32Ret = ioctl(pstInfo->fd, FBIOGET_VSCREENINFO, &stVarInfo);
	if(s32Ret < 0)
	{
		printf("GET_VSCREENINFO failed!\n");
		return HI_NULL;
	}

    if (ioctl(pstInfo->fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)
    {
        printf("set screen original show position failed!\n");
        return HI_NULL;
    }
    maxW = gVoFbWidth;
	maxH = gVoFbHeight;
    stVarInfo.xres = stVarInfo.xres_virtual = maxW;
    stVarInfo.yres = stVarInfo.yres_virtual = maxH;
    s32Ret = ioctl(pstInfo->fd, FBIOPUT_VSCREENINFO, &stVarInfo);
    if(s32Ret < 0)
	{
		printf("PUT_VSCREENINFO failed!\n");
		return HI_NULL;
	}
    switch (pstInfo->ctrlkey)
	{
		case 0 :
		{
			stLayerInfo.BufMode = HIFB_LAYER_BUF_ONE;
			stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE;
			break;
		}

		case 1 :
		{
			stLayerInfo.BufMode = HIFB_LAYER_BUF_DOUBLE;
		    stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE;
			break;
		}

		default:
		{
			stLayerInfo.BufMode = HIFB_LAYER_BUF_NONE;
			stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE;
		}
	}
    s32Ret = ioctl(pstInfo->fd, FBIOPUT_LAYER_INFO, &stLayerInfo);
    if(s32Ret < 0)
	{
		printf("PUT_LAYER_INFO failed!\n");
		return HI_NULL;
	}
	Show = HI_TRUE;
    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &Show) < 0)
    {
        printf("FBIOPUT_SHOW_HIFB failed!\n");
        return HI_NULL;
    }

	if (HI_FAILURE == HI_MPI_SYS_MmzAlloc(&(stCanvasBuf.stCanvas.u32PhyAddr), ((void**)&pBuf),
            NULL, NULL, maxW*maxH*2))
    {
        printf("allocate memory (maxW*maxH*2 bytes) failed\n");
        return HI_NULL;
    }

    stCanvasBuf.stCanvas.u32Height = maxH;
    stCanvasBuf.stCanvas.u32Width = maxW;
    stCanvasBuf.stCanvas.u32Pitch = maxW*2;
    stCanvasBuf.stCanvas.enFmt = HIFB_FMT_ARGB1555;
    memset(pBuf, 0x00, stCanvasBuf.stCanvas.u32Pitch*stCanvasBuf.stCanvas.u32Height);
    g_pwMenuViraddr = pBuf;
/*
	s32Ret = HI_TDE2_Open();
	if(s32Ret < 0)
	{
		printf("HI_TDE2_Open failed :%d!\n",s32Ret);
		HI_MPI_SYS_MmzFree(Phyaddr, Viraddr);
		return THREAD_RET_OK;
	}
*/
	//printf("expected:two red  line!\n");
	/*time to play*/
	//for(i = 0; i < SAMPLE_IMAGE_NUM; i++)
	while (1)
	{

		if (gMenuRefreshFlg == 0)
		{
			Sleep(100);
			continue;
		}

		gMenuRefreshFlg = 0;
		//printf("refresh sd1 \n\t");
/*
		Line(0, maxH/6, maxW, maxH/6+1, pBuf);
		Line( maxW/6, 0, maxW/6+1, maxH, pBuf);

		Line(0, maxH*2/6, maxW, maxH*2/6+1, pBuf);
		Line( maxW*2/6, 0, maxW*2/6+1, maxH, pBuf);

		Line(0, maxH*3/6, maxW, maxH*3/6+1, pBuf);
		Line( maxW*3/6, 0, maxW*3/6+1, maxH, pBuf);

		Line(0, maxH*4/6, maxW, maxH*4/6+1, pBuf);
		Line( maxW*4/6, 0, maxW*4/6+1, maxH, pBuf);

		Line(0, maxH*5/6, maxW, maxH*5/6+1, pBuf);
		Line( maxW*5/6, 0, maxW*5/6+1, maxH, pBuf);
*/
		/*
		// 1. start job
		s32Handle = HI_TDE2_BeginJob();
		if(HI_ERR_TDE_INVALID_HANDLE == s32Handle)
		{
			printf("start job failed!\n");
			HI_MPI_SYS_MmzFree(Phyaddr, Viraddr);
			HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
			return THREAD_RET_OK;
		}

		// 3. submit job
		s32Ret = HI_TDE2_EndJob(s32Handle, HI_FALSE, HI_TRUE, 10);
		if(s32Ret < 0)
		{
			printf("Line:%d,HI_TDE2_EndJob failed,ret=0x%x!\n", __LINE__, s32Ret);
			HI_TDE2_CancelJob(s32Handle);
			HI_MPI_SYS_MmzFree(Phyaddr, Viraddr);
			HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
			return THREAD_RET_OK;
		}
*/
	    stCanvasBuf.UpdateRect.x = 0;
	    stCanvasBuf.UpdateRect.y = 0;
	    stCanvasBuf.UpdateRect.w = maxW;
	    stCanvasBuf.UpdateRect.h = maxH;
	    s32Ret = ioctl(pstInfo->fd, FBIO_REFRESH, &stCanvasBuf);
	    if(s32Ret < 0)
		{
			printf("REFRESH failed!\n");
			HI_MPI_SYS_MmzFree(Phyaddr, Viraddr);
			HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
			return HI_NULL;
		}

		Sleep(50);
	}
	HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
    close(pstInfo->fd);
	return HI_NULL;
}


HI_S32 SAMPLE_VI_SetUserPic(HI_CHAR *pszYuvFile, HI_U32 u32Width, HI_U32 u32Height,
        HI_U32 u32Stride, VIDEO_FRAME_INFO_S *pstFrame)
{
    FILE *pfd;
    VI_USERPIC_ATTR_S stUserPicAttr;

    /* open YUV file */
    pfd = fopen(pszYuvFile, "rb");
    if (!pfd)
    {
        printf("open file -> %s fail \n", pszYuvFile);
        return -1;
    }

    /* read YUV file. WARNING: we only support planar 420) */
    if (SAMPLE_COMM_VI_GetVFrameFromYUV(pfd, u32Width, u32Height, u32Stride, pstFrame))
    {
        return -1;
    }
    fclose(pfd);

    stUserPicAttr.bPub= HI_TRUE;
    stUserPicAttr.enUsrPicMode = VI_USERPIC_MODE_PIC;
    memcpy(&stUserPicAttr.unUsrPic.stUsrPicFrm, pstFrame, sizeof(VIDEO_FRAME_INFO_S));
    if (HI_MPI_VI_SetUserPic(0, &stUserPicAttr))
    {
        return -1;
    }

    printf("set vi user pic ok, yuvfile:%s\n", pszYuvFile);
    return HI_SUCCESS;
}

HI_S32 SAMPLE_VIO_4_960H(HI_VOID)
{
	pthread_t phifb0 = -1;
    PTHREAD_HIFB_SAMPLE_INFO stInfo0;
        
	SAMPLE_VI_MODE_E enViMode = SAMPLE_VI_MODE_4_D1;

	HI_U32 u32ViChnCnt = 4;
	HI_S32 s32VpssGrpCnt = 4;
	
	VB_CONF_S stVbConf;
	VI_CHN ViChn;
	VPSS_GRP VpssGrp;
	VPSS_GRP_ATTR_S stGrpAttr;
	VPSS_CHN VpssChn_VoHD0 = VPSS_PRE0_CHN;
	VO_DEV VoDev;
	VO_CHN VoChn;
	VO_PUB_ATTR_S stVoPubAttr,stVoPubAttrSD; 
	SAMPLE_VO_MODE_E enVoMode, enPreVoMode;
	VIDEO_FRAME_INFO_S stFrame;
	
	HI_S32 i;
	HI_S32 s32Ret = HI_SUCCESS;
	HI_U32 u32BlkSize;
	HI_CHAR ch;
	SIZE_S stSize;
	HI_U32 u32WndNum;
	HI_U32 u32Depth;
	
	VO_WBC_ATTR_S stWbcAttr;
	 printf("###SAMPLE_VIO_4_960H start!\n");
	/******************************************
	 step  1: init variable 
	******************************************/
	gs_u32ViFrmRate = (VIDEO_ENCODING_MODE_PAL== gs_enNorm)?25:30;
	
	memset(&stVbConf,0,sizeof(VB_CONF_S));

	u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
				PIC_960H, SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);
	stVbConf.u32MaxPoolCnt = 128;

	/* video buffer*/
	//todo: vb=15
	stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;
	stVbConf.astCommPool[0].u32BlkCnt = u32ViChnCnt * 3;

	/******************************************
	 step 2: mpp system init. 
	******************************************/
	s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("system init failed with %d!\n", s32Ret);
		goto END_8D1_0;
	}

	/******************************************
	 step 3: start vi dev & chn
	******************************************/
	s32Ret = SAMPLE_COMM_VI_Start(enViMode, gs_enNorm);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("start vi failed!\n");
		goto END_8D1_0;
	}
	
	/* set max depth */
	ViChn = 0;
	u32Depth = 2;
	s32Ret = HI_MPI_VI_SetFrameDepth(ViChn, u32Depth);
	if (HI_SUCCESS != s32Ret)
	{
		printf("set max depth err:0x%x\n", s32Ret);
	}

	/******************************************
	 step 3: start vpss and vi bind vpss
	******************************************/
	s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, PIC_960H, &stSize);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed!\n");
		goto END_8D1_0;
	}
	
	stGrpAttr.u32MaxW = stSize.u32Width;
	stGrpAttr.u32MaxH = stSize.u32Height;
	stGrpAttr.bDrEn = HI_FALSE;
	stGrpAttr.bDbEn = HI_FALSE;
	stGrpAttr.bIeEn = HI_TRUE;
	stGrpAttr.bNrEn = HI_TRUE;
	stGrpAttr.bHistEn = HI_FALSE;
	stGrpAttr.enDieMode = VPSS_DIE_MODE_AUTO;
	stGrpAttr.enPixFmt = SAMPLE_PIXEL_FORMAT;
	u8 bChlFlgBuf[5];
	memset(bChlFlgBuf, 0, sizeof(bChlFlgBuf));
	bChlFlgBuf[0] = 1;
	bChlFlgBuf[4] = 1;
	s32Ret = SAMPLE_COMM_VPSS_StartEx(s32VpssGrpCnt, &stSize, bChlFlgBuf, &stGrpAttr);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("Start Vpss failed!\n");
		goto END_8D1_1;
	}
	s32Ret = SAMPLE_COMM_VI_BindVpss(enViMode);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("Vi bind Vpss failed!\n");
		goto END_8D1_2;
	}

#if 0
	/******************************************
	 step 6: start vo HD0 (HDMI+VGA), multi-screen, you can switch mode
	******************************************/
	printf("start vo HD0.\n");
	VoDev = SAMPLE_VO_DEV_DHD0;
	u32WndNum = 4;
	enVoMode = VO_MODE_4MUX;
	
	if(VIDEO_ENCODING_MODE_PAL == gs_enNorm)
	{
		stVoPubAttr.enIntfSync = VO_OUTPUT_1024x768_60;
	}
	else
	{
		stVoPubAttr.enIntfSync = VO_OUTPUT_1024x768_60;
	}
#ifdef HI_FPGA
	//stVoPubAttr.enIntfType = VO_INTF_HDMI|VO_INTF_VGA|VO_INTF_BT1120;
#else 
	//stVoPubAttr.enIntfType = VO_INTF_HDMI|VO_INTF_VGA;
	stVoPubAttr.enIntfType = VO_INTF_VGA;
#endif

	stVoPubAttr.u32BgColor = 0x000000ff;
	stVoPubAttr.bDoubleFrame = HI_TRUE;
	
	s32Ret = SAMPLE_COMM_VO_StartDevLayer(VoDev, &stVoPubAttr, gs_u32ViFrmRate);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("Start SAMPLE_COMM_VO_StartDevLayer failed!\n");
		goto END_8D1_4;
	}
	
	s32Ret = SAMPLE_COMM_VO_StartChn(VoDev, &stVoPubAttr, enVoMode);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("Start SAMPLE_COMM_VO_StartChn failed!\n");
		goto END_8D1_5;
	}

	/* if it's displayed on HDMI, we should start HDMI */
	if (stVoPubAttr.enIntfType & VO_INTF_HDMI)
	{
		if (HI_SUCCESS != SAMPLE_COMM_VO_HdmiStart(stVoPubAttr.enIntfSync))
		{
			SAMPLE_PRT("Start SAMPLE_COMM_VO_HdmiStart failed!\n");
			goto END_8D1_5;
		}
	}
	
	for(i=0;i<u32WndNum;i++)
	{
		VoChn = i;
		VpssGrp = i;
		
		s32Ret = SAMPLE_COMM_VO_BindVpss(VoDev, VoChn, VpssGrp, VpssChn_VoHD0);
		if (HI_SUCCESS != s32Ret)
		{
			SAMPLE_PRT("Start VO failed!\n");
			goto END_8D1_5;
		}
	}
#endif


#if 0
	/******************************************
	step 7: start vo SD1 (CVBS) (WBC target) 
	******************************************/
	printf("start vo SD1: wbc from hd0\n");
	VoDev = SAMPLE_VO_DEV_DSD1;
	u32WndNum = 1;
	enVoMode = VO_MODE_1MUX;

	stVoPubAttrSD.enIntfSync = gs_enIntfSync;//VO_OUTPUT_PAL;
	stVoPubAttrSD.enIntfType = VO_INTF_CVBS;
	stVoPubAttrSD.u32BgColor = 0x000000ff;
	stVoPubAttrSD.bDoubleFrame = HI_FALSE;
	s32Ret = SAMPLE_COMM_VO_StartDevLayer(VoDev, &stVoPubAttrSD, gs_u32ViFrmRate);
	if (HI_SUCCESS != s32Ret)
	{
		  SAMPLE_PRT("SAMPLE_COMM_VO_StartDevLayer failed!\n");
		  goto END_8D1_5;
	}

	s32Ret = SAMPLE_COMM_VO_StartChn(VoDev, &stVoPubAttrSD, enVoMode);
	if (HI_SUCCESS != s32Ret)
	{
		  SAMPLE_PRT("SAMPLE_COMM_VO_StartChn failed!\n");
		  goto END_8D1_6;
	}
	  
	s32Ret = SAMPLE_COMM_VO_GetWH(gs_enIntfSync, \
					  &stWbcAttr.stTargetSize.u32Width, \
					  &stWbcAttr.stTargetSize.u32Height, \
					  &stWbcAttr.u32FrameRate);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("SAMPLE_COMM_VO_GetWH failed!\n");
		goto END_8D1_6;
	}
	stWbcAttr.enPixelFormat = SAMPLE_PIXEL_FORMAT;
	stWbcAttr.enDataSource = VO_WBC_DATASOURCE_MIXER;

	s32Ret = HI_MPI_VO_SetWbcAttr(SAMPLE_VO_DEV_DHD0, &stWbcAttr);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("HI_MPI_VO_SetWbcAttr failed!\n");
		goto END_8D1_6;
	}

	s32Ret = HI_MPI_VO_EnableWbc(SAMPLE_VO_DEV_DHD0);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("HI_MPI_VO_SetWbcAttr failed!\n");
		goto END_8D1_7;
	}

	s32Ret = SAMPLE_COMM_VO_BindVoWbc(SAMPLE_VO_DEV_DHD0, VoDev, 0);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("HI_MPI_VO_SetWbcAttr failed0!\n");
		goto END_8D1_7;
	}
/*
 	s32Ret = SAMPLE_COMM_VO_BindVoWbc(SAMPLE_VO_DEV_DHD0, VoDev, 1);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("HI_MPI_VO_SetWbcAttr failed1!\n");
		goto END_8D1_7;
	}
	s32Ret = SAMPLE_COMM_VO_BindVoWbc(SAMPLE_VO_DEV_DHD0, VoDev, 2);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("HI_MPI_VO_SetWbcAttr failed2!\n");
		goto END_8D1_7;
	}

	s32Ret = SAMPLE_COMM_VO_BindVoWbc(SAMPLE_VO_DEV_DHD0, VoDev, 3);
	if (HI_SUCCESS != s32Ret)
	{
		SAMPLE_PRT("HI_MPI_VO_SetWbcAttr failed3!\n");
		goto END_8D1_7;
	}*/
#else

/******************************************
	step 5: start vo SD1(CVBS)
	******************************************/

	printf("start vo SD1.\n");
	VoDev = SAMPLE_VO_DEV_DSD1;
	u32WndNum = 1;
	enVoMode = VO_MODE_4MUX;

	stVoPubAttr.enIntfSync = gs_enIntfSync;//VO_OUTPUT_PAL;
	stVoPubAttr.enIntfType = VO_INTF_CVBS;
	stVoPubAttr.u32BgColor = 0x000000ff;
	stVoPubAttr.bDoubleFrame = HI_FALSE;
	s32Ret = SAMPLE_COMM_VO_StartDevLayer(VoDev, &stVoPubAttr, gs_u32ViFrmRate);
	if (HI_SUCCESS != s32Ret)
	{
		 SAMPLE_PRT("SAMPLE_COMM_VO_StartDevLayer failed!\n");
		 goto END_8D1_3;
	}

	s32Ret = SAMPLE_COMM_VO_StartChn(VoDev, &stVoPubAttr, enVoMode);
	if (HI_SUCCESS != s32Ret)
	{
		 SAMPLE_PRT("SAMPLE_COMM_VO_StartChn failed!\n");
		 goto END_8D1_4;
	}
		
	for(i=0;i<u32WndNum;i++)
	{
		VoChn = i;
		VpssGrp = i;
		
		s32Ret = SAMPLE_COMM_VO_BindVpss(VoDev, VoChn, VpssGrp, VPSS_BYPASS_CHN);
		if (HI_SUCCESS != s32Ret)
		{
			SAMPLE_PRT("Start VO failed!\n");
			goto END_8D1_5;
		}
	}

    /******************************************
     step 5: set novideo pic
    ******************************************/
    /* set novideo pic */
    s32Ret = SAMPLE_VI_SetUserPic("./pic_704_576_p420_novideo01.yuv", 704, 576, 704, &stFrame);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("SAMPLE_COMM_VI_SetUserPic failed!\n");
        goto END_8D1_5;
    }

/*	
	VoChn = 0;
	ViChn = 0;
	s32Ret = SAMPLE_COMM_VO_BindVi(VoDev,VoChn, ViChn);
	if (HI_SUCCESS != s32Ret)
	{
		 SAMPLE_PRT("SAMPLE_COMM_VO_BindVpss failed!\n");
		 goto END_8D1_4;
	}
*/

/*
	for(i=0;i<u32WndNum;i++)
	{
		VoChn = i;
		ViChn = i;
		
		s32Ret = SAMPLE_COMM_VO_BindVi(VoDev,VoChn, ViChn);
		if (HI_SUCCESS != s32Ret)
		{
			 SAMPLE_PRT("SAMPLE_COMM_VO_BindVpss failed!\n");
			 goto END_8D1_4;
		}
	}
*/

#endif


	/******************************************
	step 8: DSD1 switch mode 
	******************************************/
	ViChn = 0;
	VoDev = SAMPLE_VO_DEV_DSD1;//SAMPLE_VO_DEV_DHD0;
	enVoMode = VO_MODE_4MUX;
		
		
	stInfo0.layer   =  2;
    stInfo0.fd      = -1;
    stInfo0.ctrlkey =  2;
		
    NewThread(MenuThread, (void *)&stInfo0, 8*1024, THREAD_PRIORITY_ABOVE_NORMAL);
	//pthread_create(&phifb0, 0, SAMPLE_HIFB_PANDISPLAY, (void *)(&stInfo0));
	
	
	while(1)
	{				
		/*		
		HI_MPI_VI_GetFrame(ViChn, &stFrame);
		//......
		HI_MPI_VO_SendFrame(SAMPLE_VO_DEV_DSD1, 0, &stFrame);		
		HI_MPI_VI_ReleaseFrame(ViChn, &stFrame);				
		continue;
		*/
		
		
		enPreVoMode = enVoMode;
	
		printf("please choose preview mode, press 'q' to exit this sample.\n"); 
		printf("\t0) 1 preview\n");
		printf("\t1) 4 preview\n");
		printf("\t2) 8 preview\n");
		printf("\tq) quit\n");
 
		ch = getchar();
		getchar();
		if ('0' == ch)
		{
			u32WndNum = 1;
			enVoMode = VO_MODE_1MUX;
		}
		else if ('1' == ch)
		{
			u32WndNum = 4;
			enVoMode = VO_MODE_4MUX;
		}
		/*Indeed only 8 chns show*/
		else if ('2' == ch)
		{
			u32WndNum = 9;
			enVoMode = VO_MODE_9MUX;
		}
		else if  ('s' == ch)
		{
			SAMPLE_MISC_WbcDump(ViChn, 128);
			continue;
		}
		else if ('q' == ch)
		{
			break;
		}
		else
		{
			SAMPLE_PRT("preview mode invaild! please try again.\n");
			continue;
		}
		SAMPLE_PRT("vo(%d) switch to %d mode\n", VoDev, u32WndNum);

		s32Ret= HI_MPI_VO_SetAttrBegin(VoDev);
		if (HI_SUCCESS != s32Ret)
		{
			SAMPLE_PRT("Start VO failed!\n");
			goto END_8D1_7;
		}
		
		s32Ret = SAMPLE_COMM_VO_StopChn(VoDev, enPreVoMode);
		if (HI_SUCCESS != s32Ret)
		{
			SAMPLE_PRT("Start VO failed!\n");
			goto END_8D1_7;
		}

		s32Ret = SAMPLE_COMM_VO_StartChn(VoDev, &stVoPubAttr, enVoMode);
		if (HI_SUCCESS != s32Ret)
		{
			SAMPLE_PRT("Start VO failed!\n");
			goto END_8D1_7;
		}
		s32Ret= HI_MPI_VO_SetAttrEnd(VoDev);
		if (HI_SUCCESS != s32Ret)
		{
			SAMPLE_PRT("Start VO failed!\n");
			goto END_8D1_7;
		}
		
	}

	/******************************************
	 step 8: exit process
	******************************************/

END_8D1_7:
	SAMPLE_COMM_VO_UnBindVoWbc(SAMPLE_VO_DEV_DSD1, 0);
	HI_MPI_VO_DisableWbc(SAMPLE_VO_DEV_DHD0);

END_8D1_6:
	VoDev = SAMPLE_VO_DEV_DSD1;
	VoChn = 0;
	enVoMode = VO_MODE_1MUX;
	SAMPLE_COMM_VO_StopChn(VoDev, enVoMode);
	SAMPLE_COMM_VO_StopDevLayer(VoDev);

END_8D1_5:
	if (stVoPubAttr.enIntfType & VO_INTF_HDMI)
	{
		SAMPLE_COMM_VO_HdmiStop();
	}
	VoDev = SAMPLE_VO_DEV_DHD0;
	u32WndNum = 16;
	enVoMode = VO_MODE_16MUX;
	/*disableChn ,?*/
	SAMPLE_COMM_VO_StopChn(VoDev, enVoMode);
	for(i=0;i<u32WndNum;i++)
	{
		VoChn = i;
		VpssGrp = i;
		SAMPLE_COMM_VO_UnBindVpss(VoDev,VoChn,VpssGrp,VpssChn_VoHD0);
	}
	SAMPLE_COMM_VO_StopDevLayer(VoDev);

END_8D1_4:
#if HICHIP == HI3521_V100
	VoDev = SAMPLE_VO_DEV_DSD1;
	VoChn = 0;
	enVoMode = VO_MODE_1MUX;
	
	SAMPLE_COMM_VO_UnBindVi(VoDev,VoChn); 
	SAMPLE_COMM_VO_StopChn(VoDev, enVoMode);
	SAMPLE_COMM_VO_StopDevLayer(VoDev);
#endif
END_8D1_3:	//vi unbind vpss
	SAMPLE_COMM_VI_UnBindVpss(enViMode);
END_8D1_2:	//vpss stop
	SAMPLE_COMM_VPSS_Stop(s32VpssGrpCnt, VPSS_MAX_CHN_NUM);
END_8D1_1:	//vi stop
	SAMPLE_COMM_VI_Stop(enViMode);
END_8D1_0:	//system exit
	SAMPLE_COMM_SYS_Exit();
	
	return s32Ret;
}







/******************************************************************************
* function    : main()
* Description : video preview sample
******************************************************************************/
TThreadRet VideoThread(void* pvPara)
{
    HI_S32 s32Ret;
    
     
    printf("###VideoThread start!\n");
  
    switch (0)
    {
        case '0'://PAL
        	system("rmmod nvp6114_ex.ko");
          	system("insmod ./ko/extdrv/nvp6114_ex.ko  outmode=2 vdec_mode=1");
          	
          	gs_enIntfSync = VO_OUTPUT_PAL;
          	gs_enNorm = VIDEO_ENCODING_MODE_PAL;

          	gVoFbWidth = 720;
			gVoFbHeight = 576;
            break;
        case '1'://NTSC
            system("rmmod nvp6114_ex.ko");
          	system("insmod ./ko/extdrv/nvp6114_ex.ko  outmode=2 vdec_mode=0");
          	
          	gs_enIntfSync = VO_OUTPUT_NTSC;
          	gs_enNorm = VIDEO_ENCODING_MODE_NTSC;
          	gVoFbWidth = 720;
			gVoFbHeight = 480;
            break;
       
        default: //PAL
            printf("the index is invaild!, default to PAL\n");
            system("rmmod nvp6114_ex.ko");
          	system("insmod ./ko/extdrv/nvp6114_ex.ko  outmode=2 vdec_mode=1");
          	
          	gs_enIntfSync = VO_OUTPUT_PAL;
          	gs_enNorm = VIDEO_ENCODING_MODE_PAL;
          	gVoFbWidth = 720;
			gVoFbHeight = 576;
           // return NULL;
    }

	

	s32Ret = SAMPLE_VIO_4_960H();

    if (HI_SUCCESS == s32Ret)
        printf("###program exit normally!\n");
    else
        printf("###program exit abnormally!\n");
        
        
    exit(s32Ret);
    return NULL;
}



void RefreshMenu(u8 *pbLcdBuf)
{
	if (g_pwMenuViraddr == NULL)
	{
		return;
	}
	//printf("refresh lcd \n\t");

	for (int y=0; y<LCD_SIM_HEIGHT; y++)
	{
		for (int x=0; x<LCD_SIM_WIDTH; x++)
		{
			for (int i=0; i<8; i++)
			{
				if ((pbLcdBuf[y*LCD_SIM_WIDTH_BYTE + (x>>3)] & (1 << (7 - (x & 0x07)))) == 0)
					g_pwMenuViraddr[y * LCD_SIM_WIDTH + x] = 0;
				else
					g_pwMenuViraddr[y * LCD_SIM_WIDTH + x] = HIFB_RED_1555;
			}
		}
	}

	gMenuRefreshFlg = 1;
}

/*
#include "SWidget.h"
void clear_screen(void)
{
    WIDGET_Lock();
    memset((char*)g_pwMenuViraddr, 0, LCD_SIM_WIDTH_BYTE*LCD_SIM_HEIGHT);
    WIDGET_UnLock();
}

//extern unsigned int SysGetKey();
int sys_getchar(void)
{
    //unsigned int newKey = SysGetKey();

    return 0;
}

void set_pix(int x, int y, int value)
{
	if (g_pwMenuViraddr == NULL)
	{
		return;
	}

    x %= LCD_SIM_WIDTH;
    y %= LCD_SIM_HEIGHT;

    g_pwMenuViraddr[y * LCD_SIM_WIDTH + x] = value;
}


void RefreshMenu(u8 *pbLcdBuf)
{



}
*/
